﻿/*
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
*
* Author	: Bruce Liang
* Website	: http://www.jessma.org
* Project	: https://github.com/ldcsaa
* Blog		: http://www.cnblogs.com/ldcsaa
* Wiki		: http://www.oschina.net/p/hp-socket
* QQ Group	: 75375912, 44636872
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "GlobalDef.h"
#include "Singleton.h"
#include "STLHelper.h"
#include "RingBuffer.h"
#include "PrivateHeap.h"
#include "CriSec.h"

/**
 * 链表中的基础项元素，双向结点结构，与redis中的sds动态字符串库使用的技巧有异曲同工之妙
 * TItem对象[内存模型] = [TItem对象段，buffer段]
 * [TItem对象段] = buffer段的信息段[
 * 	next：指向下一个Item项
 * 	last：指向上一个Item项
 * 	capacity：buffer段的容量大小
 * 	head：指向buffer段，固定不变
 * 	begin：指向当前Item的buffer，当读取buffer时会做偏移
 * 	end：指向写入数据的最后位置
 * ]
 * [buffer段] = 数据段
 */
struct TItem
{
	template<typename T> friend struct	TSimpleList;
	template<typename T> friend class	CNodePoolT;

	friend struct	TItemList;
	friend struct	TBuffer;

public:
	/**
	 * copy数据到buffer中，不一定会将所有数据都copy到buffer中
	 * pData：数据源
	 * length：数据源的长度
	 * return：返回copy到buffer中的数据长度
	 */
	int		Cat		(const BYTE* pData, int length);

	//copy Item对象
	int		Cat		(const TItem& other);
	/**
	 * 从buffer中拉取数据copy到pData中，不一定拉取了长度为length的数据
	 * 此函数会改变begin位置
	 * pData: 外部接收区
	 * length：需要拉取数据长度
	 * return：实际拉取数据的长度
	 */
	int		Fetch	(BYTE* pData, int length);
	/**
	 * 与Fetch类似但不会改变begin位置
	 */
	int		Peek	(BYTE* pData, int length);

	/**
	 * 将数据段信息中已写入数据的长度增加length长度，此函数会改变end位置
	 * length: 偏移长度
	 * return: 实际偏移长度
	 * 已写入数据的长度不会超过buffer段的容量
	 */
	int		Increase(int length);

	/**
	 * 与Fetch类似，但只做begin的偏移
	 */
	int		Reduce	(int length);

	/**
	 * 重置begin && end
	 * first: begin的偏移量，相对与head
	 * last: end的偏移量，相对与head
	 * 偏移量不能超过buffer段容量
	 */
	void	Reset	(int first = 0, int last = 0);

	//返回当前未读取的数据项指向
	BYTE*		Ptr		()			{return begin;}
	const BYTE*	Ptr		()	const	{return begin;}
	//返回当前未读取的数据项长度
	int			Size	()	const	{return (int)(end - begin);}
	//返回buffer段当前可copy的长度（buffer剩余可写长度）
	int			Remain	()	const	{return capacity - (int)(end - head);}
	//返回buffer段的长度
	int			Capacity()	const	{return capacity;}
	//判断是否没有copy的数据
	bool		IsEmpty	()	const	{return Size()	 == 0;}
	//判断当前buffer段是否被填满
	bool		IsFull	()	const	{return Remain() == 0;}

public:
	operator		BYTE*	()			{return Ptr();}
	operator const	BYTE*	() const	{return Ptr();}

public:
	//静态的构造方法，构建者模式
	static TItem* Construct(CPrivateHeap& heap,
							int		capacity	= DEFAULT_ITEM_CAPACITY,
							BYTE*	pData		= nullptr,
							int		length		= 0);
	//静态的析构方法
	static void Destruct(TItem* pItem);

private:
	//对此特例模板函数友元，new定位调用TItem构造函数
	friend TItem* ConstructObject<>(TItem*, CPrivateHeap&, BYTE*&, int&, BYTE*&, int&);
	//对此特例模板函数友元，调用TItem析构函数
	friend void DestructObject<>(TItem*);

	TItem(CPrivateHeap& hp, BYTE* pHead, int cap = DEFAULT_ITEM_CAPACITY, BYTE* pData = nullptr, int length = 0)
	: heap(hp), head(pHead), begin(pHead), end(pHead), capacity(cap), next(nullptr), last(nullptr)
	{
		if(pData != nullptr && length != 0)
			Cat(pData, length);
	}

	~TItem() {}

	//delete 不需要编译器生成的默认的拷贝构造、赋值函数
	DECLARE_NO_COPY_CLASS(TItem)

public:
	//默认的元素容量大小
	static const DWORD DEFAULT_ITEM_CAPACITY;

private:
	CPrivateHeap& heap; //私有堆

private:
	TItem* next; //指向下一个Item项
	TItem* last; //指向上一个Item项

	int		capacity; //当前项的容量
	BYTE*	head; //指向当前Item的buffer
	BYTE*	begin; //指向当前Item的buffer，当读取buffer时会做偏移
	BYTE*	end; //指向写入数据的最后位置
};

/**
 * 简单的双向链表实现，主要兼容TItem
 * 非线程安全的
 */
template<class T> struct TSimpleList
{
public:
	//从左边添加一个结点项
	T* PushFront(T* pItem)
	{
		//判断左边指向
		if(pFront != nullptr)
		{
			//将当前左边结点的上一项的指向赋值为新添加的结点
			pFront->last = pItem;
			//将新添加的结点的下一项的指向赋值为当前左边结点
			pItem->next	 = pFront;
		}
		else
		{
			//首次添加结点
			pItem->last = nullptr;
			pItem->next = nullptr;
			//更改当前右边结点指向
			pBack		= pItem;
		}
		//更新当前左结点
		pFront = pItem;
		++size;//增加链表长度记录
		//返回新添加的结点项
		return pItem;
	}

	/**
	 * 从右边添加一个结点项
	 */
	T* PushBack(T* pItem)
	{
		//非首次添加
		if(pBack != nullptr)
		{
			//将当前右边结点的下一项指向赋值为新添加的结点
			pBack->next	= pItem;
			//将新添加的结点的上一项指向赋值为当前右结点
			pItem->last	= pBack;
		}
		else
		{
			//首次添加
			pItem->last = nullptr;
			pItem->next = nullptr;
			//更改当前左边结点指向
			pFront		= pItem;
		}

		//更新当前右结点指向
		pBack = pItem;
		++size;//增加链表长度记录
		//返回新添加的结点项
		return pItem;
	}

	/**
	 * 从链表左边取出一个元素
	 * return：取出链表中左边第一个元素，若链表中没有元素则返回nullptr
	 */
	T* PopFront()
	{
		//取出元素
		T* pItem = pFront;

		//若链表中存在其他元素
		if(pFront != pBack)
		{
			//更新链表当前左边结点指向为下一元素
			pFront = pFront->next;
			//更新上一元素指向为nullptr，此时元素为过去的下一项
			pFront->last = nullptr;
		}
		else if(pFront != nullptr)
		{
			//若不存在其他元素则清空链表左右指向
			pFront	= nullptr;
			pBack	= nullptr;
		}

		//若取出了元素则清空其前后指向
		if(pItem != nullptr)
		{
			pItem->next = nullptr;
			pItem->last = nullptr;
			//减去链表长度记录
			--size;
		}
		//return...
		return pItem;
	}

	/**
	 * 从链表的右边取出元素
	 * return: 取出链表中右边第一个元素，若链表中没有元素则返回nullptr
	 */
	T* PopBack()
	{
		//取出元素
		T* pItem = pBack;

		//若链表中存在其他元素
		if(pFront != pBack)
		{
			//更新链表右边指向，使得指向前一个元素
			pBack = pBack->last;
			//更新元素下一个指向
			pBack->next	= nullptr;
		}
		else if(pBack != nullptr)
		{
			//若没有其他元素则清空链表左右指向
			pFront	= nullptr;
			pBack	= nullptr;
		}

		//若取出了元素，清空元素的指向属性
		if(pItem != nullptr)
		{
			pItem->next = nullptr;
			pItem->last = nullptr;
			//减去链表长度记录
			--size;
		}

		return pItem;
	}

	/**
	 * 连接另一个链表使得其元素追加到当前链表之后
	 * 时间与空间均为O(1)
	 * return: 当前链表
	 */
	TSimpleList<T>& Shift(TSimpleList<T>& other)
	{
		//不追加自己，追加的链表存在元素
		//边界检查
		if(&other != this && other.size > 0)
		{
			//若当前链表中具有元素
			if(size > 0)
			{
				//追加到当前链表后
				pBack->next = other.pFront;
				//更改另一个链表首元素的上一个指向
				other.pFront->last = pBack;
			}
			else
			{
				//若当前链表中没有元素则替换
				pFront = other.pFront;
			}
			//更新当前链表右边指向
			pBack	 = other.pBack;
			//更新当前链表长度记录
			size	+= other.size;
			//使另一个链表释放其资源记录
			other.Reset();
		}

		return *this;
	}

	//清空并释放所有结点元素
	void Clear()
	{
		if(size > 0)
		{
			T* pItem;
			while((pItem = PopFront()) != nullptr)
				T::Destruct(pItem);
		}
	}

	//链表的左边指向
	T*		Front	()	const	{return pFront;}
	//链表的右边指向
	T*		Back	()	const	{return pBack;}
	//链表的长度
	int		Size	()	const	{return size;}
	//链表是否为空
	bool	IsEmpty	()	const	{return size == 0;}

public:
	TSimpleList()	{Reset();}
	~TSimpleList()	{Clear();}

	//链表不支持拷贝构造与赋值操作
	DECLARE_NO_COPY_CLASS(TSimpleList<T>)

private:
	//清空链表信息
	void Reset()
	{
		pFront	= nullptr;
		pBack	= nullptr;
		size	= 0;
	}

private:
	//链表的长度
	int	size;
	//链表左边指向
	T*	pFront;
	//链表右边指向
	T*	pBack;
};

/**
 * 结点池
 */
template<class T> class CNodePoolT
{
public:
	/**
	 * 将外部数据项添加到环形池中
	 * pItem: 外部数据项
	 * 
	 * 如果添加失败则会销毁外部数据项（pItem）
	 * 可用于对象回收
	 */
	void PutFreeItem(T* pItem)
	{
		ASSERT(pItem != nullptr);

		if(!m_lsFreeItem.TryPut(pItem))
			T::Destruct(pItem);
	}

	/**
	 * 将外部链表数据项依次添加到环形池中
	 * lsItem: 外部链表数据项
	 * for(item: items)
	 * 	PutFreeItem(item)
	 */
	void PutFreeItem(TSimpleList<T>& lsItem)
	{
		if(lsItem.IsEmpty())
			return;

		T* pItem;
		while((pItem = lsItem.PopFront()) != nullptr)
			PutFreeItem(pItem);
	}

	/**
	 * 尝试从环形池中获取一个数据项
	 * return: 返回一个数据项，此处有可能为nullptr
	 * 若无法从环形池中得到将会调用Construct构建一个并返回
	 * 返回的数据项buffer中并没有数据
	 */
	T* PickFreeItem()
	{
		T* pItem = nullptr;

		if(m_lsFreeItem.TryGet(&pItem))
			pItem->Reset();
		else
			pItem = T::Construct(m_heap, m_dwItemCapacity);

		return pItem;
	}

	/**
	 * 初始化操作
	 * 调用此方法使得重置环形池大小为m_dwPoolSize
	 */
	void Prepare()
	{
		m_lsFreeItem.Reset(m_dwPoolSize);
	}

	/**
	 * 清空并销毁环形池中的数据项
	 */
	void Clear()
	{
		T* pItem = nullptr;

		while(m_lsFreeItem.TryGet(&pItem))
			T::Destruct(pItem);

		VERIFY(m_lsFreeItem.IsEmpty());
		m_lsFreeItem.Reset();

		m_heap.Reset();
	}

public:
	void SetItemCapacity(DWORD dwItemCapacity)	{m_dwItemCapacity	= dwItemCapacity;}
	void SetPoolSize	(DWORD dwPoolSize)		{m_dwPoolSize		= dwPoolSize;}
	void SetPoolHold	(DWORD dwPoolHold)		{m_dwPoolHold		= dwPoolHold;}
	DWORD GetItemCapacity	()					{return m_dwItemCapacity;}
	DWORD GetPoolSize		()					{return m_dwPoolSize;}
	DWORD GetPoolHold		()					{return m_dwPoolHold;}

	CPrivateHeap& GetPrivateHeap()				{return m_heap;}

public:
	CNodePoolT(	DWORD dwPoolSize	 = DEFAULT_POOL_SIZE,
				DWORD dwPoolHold	 = DEFAULT_POOL_HOLD,
				DWORD dwItemCapacity = DEFAULT_ITEM_CAPACITY)
				: m_dwPoolSize(dwPoolSize)
				, m_dwPoolHold(dwPoolHold)
				, m_dwItemCapacity(dwItemCapacity)
	{
	}

	~CNodePoolT()	{Clear();}

	DECLARE_NO_COPY_CLASS(CNodePoolT)

public:
	//元素项buffer的默认长度
	static const DWORD DEFAULT_ITEM_CAPACITY;
	//默认环形池大小
	static const DWORD DEFAULT_POOL_SIZE;
	//环形池的保留大小，暂时没用
	static const DWORD DEFAULT_POOL_HOLD;

private:
	//私有堆
	CPrivateHeap	m_heap;

	//元素项buffer的默认长度
	DWORD			m_dwItemCapacity;
	//环形池大小
	DWORD			m_dwPoolSize;
	DWORD			m_dwPoolHold;

	//环形缓冲池
	CRingPool<T>	m_lsFreeItem;
};

template<class T> const DWORD CNodePoolT<T>::DEFAULT_ITEM_CAPACITY	= TItem::DEFAULT_ITEM_CAPACITY;
template<class T> const DWORD CNodePoolT<T>::DEFAULT_POOL_SIZE		= 1200;
template<class T> const DWORD CNodePoolT<T>::DEFAULT_POOL_HOLD		= 1200;

//数据项元素池
using CItemPool = CNodePoolT<TItem>;

/**
 * 基于TSimpleList和CNodePoolT池的数据项元素链表
 */
struct TItemList : public TSimpleList<TItem>
{
	friend struct TItemPtr;

public:
	int PushTail(const BYTE* pData, int length);
	int Cat		(const BYTE* pData, int length);
	int Cat		(const TItem* pItem);
	int Cat		(const TItemList& other);
	int Fetch	(BYTE* pData, int length);
	int Peek	(BYTE* pData, int length);
	int Reduce	(int length);
	void Release();

public:
	TItemList(CItemPool& pool) : itPool(pool)
	{
	}

private:
	CItemPool& itPool;
};

/**
 * 传入的模板参数必须为整数类型（int、short、long之类的）
 * 继承自TItemList，主要拓展了其功能；
 * 增加了对数据长度的记录
 */
template<class length_t = int, typename = enable_if_t<is_integral<typename decay<length_t>::type>::value>>
struct TItemListExT : public TItemList
{
	using __super = TItemList;

public:
	TItem* PushFront(TItem* pItem)
	{
		length += pItem->Size();
		return __super::PushFront(pItem);
	}

	TItem* PushBack(TItem* pItem)
	{
		length += pItem->Size();
		return __super::PushBack(pItem);
	}

	TItem* PopFront()
	{
		TItem* pItem = __super::PopFront();

		if(pItem != nullptr)
			length -= pItem->Size();

		return pItem;
	}

	TItem* PopBack()
	{
		TItem* pItem = __super::PopBack();

		if(pItem != nullptr)
			length -= pItem->Size();

		return pItem;
	}

	TItemListExT& Shift(TItemListExT& other)
	{
		if(&other != this && other.length > 0)
		{
			length += other.length;
			other.length = 0;

			__super::Shift(other);
		}

		return *this;
	}

	void Clear()
	{
		__super::Clear();
		length = 0;
	}

	void Release()
	{
		__super::Release();
		length = 0;
	}

public:
	int PushTail(const BYTE* pData, int length)
	{
		int cat = __super::PushTail(pData, length);
		this->length += cat;

		return cat;
	}

	int Cat(const BYTE* pData, int length)
	{
		int cat = __super::Cat(pData, length);
		this->length += cat;

		return cat;
	}

	int Cat(const TItem* pItem)
	{
		int cat = __super::Cat(pItem->Ptr(), pItem->Size());
		this->length += cat;

		return cat;
	}

	int Cat(const TItemList& other)
	{
		int cat = __super::Cat(other);
		this->length += cat;

		return cat;
	}

	int Fetch(BYTE* pData, int length)
	{
		int fetch	  = __super::Fetch(pData, length);
		this->length -= fetch;

		return fetch;
	}

	int Reduce(int length)
	{
		int reduce	  = __super::Reduce(length);
		this->length -= reduce;

		return reduce;
	}
	
	/**
	 * 返回链表中所有数据长度
	 * decay模板函数（退化模板参数类型）：具体查看https://zh.cppreference.com/w/cpp/types/decay
	 */
	typename decay<length_t>::type Length() const {return length;}

public:
	TItemListExT(CItemPool& pool) : TItemList(pool), length(0)
	{
	}

	~TItemListExT()
	{
		ASSERT(length >= 0);
	}

	DECLARE_NO_COPY_CLASS(TItemListExT)

private:
	length_t length;
};

//默认int类型记录数据长度
using TItemListEx	= TItemListExT<>;
//使用具有volatile可见性的int类型记录数据长度
using TItemListExV	= TItemListExT<volatile int>;

/**
 * TItem的包装类
 */
struct TItemPtr
{
public:
	TItem* Reset(TItem* pItem = nullptr)
	{
		if(m_pItem != nullptr)
			itPool.PutFreeItem(m_pItem);

		m_pItem = pItem;

		return m_pItem;
	}

	TItem* Attach(TItem* pItem)
	{
		return Reset(pItem);
	}

	TItem* Detach()
	{
		TItem* pItem = m_pItem;
		m_pItem		 = nullptr;

		return pItem;
	}

	TItem* New()
	{
		return Attach(itPool.PickFreeItem());
	}

	bool IsValid			()				{return m_pItem != nullptr;}
	TItem* operator ->		()				{return m_pItem;}
	TItem* operator =		(TItem* pItem)	{return Reset(pItem);}
	operator TItem*			()				{return m_pItem;}
	TItem*& PtrRef			()				{return m_pItem;}
	TItem* Ptr				()				{return m_pItem;}
	const TItem* Ptr		()	const		{return m_pItem;}
	operator const TItem*	()	const		{return m_pItem;}

public:
	TItemPtr(CItemPool& pool, TItem* pItem = nullptr)
	: itPool(pool), m_pItem(pItem)
	{

	}

	TItemPtr(TItemList& ls, TItem* pItem = nullptr)
	: itPool(ls.itPool), m_pItem(pItem)
	{

	}

	~TItemPtr()
	{
		Reset();
	}

	DECLARE_NO_COPY_CLASS(TItemPtr)

private:
	CItemPool&	itPool;
	TItem*		m_pItem;
};

class CBufferPool;

struct TBuffer
{
	template<typename T> friend struct	TSimpleList;
	friend class						CBufferPool;

public:
	static TBuffer* Construct(CBufferPool& pool, ULONG_PTR dwID);
	static void Destruct(TBuffer* pBuffer);

public:
	int Cat		(const BYTE* pData, int len);
	int Cat		(const TItem* pItem);
	int Cat		(const TItemList& other);
	int Fetch	(BYTE* pData, int length);
	int Peek	(BYTE* pData, int length);
	int Reduce	(int len);

public:
	CCriSec&	CriSec	()	{return cs;}
	TItemList&	ItemList()	{return items;}

	ULONG_PTR ID		()	const	{return id;}
	int Length			()	const	{return length;}
	bool IsValid		()	const	{return id != 0;}

	DWORD GetFreeTime	()	const	{return freeTime;}

private:
	int IncreaseLength	(int len)	{return (length += len);}
	int DecreaseLength	(int len)	{return (length -= len);}

	void Reset			();

private:
	friend TBuffer* ConstructObject<>(TBuffer*, CPrivateHeap&, CItemPool&, ULONG_PTR&);
	friend void DestructObject<>(TBuffer*);

	TBuffer(CPrivateHeap& hp, CItemPool& itPool, ULONG_PTR dwID = 0)
	: heap(hp), items(itPool), id(dwID), length(0)
	{
	}

	~TBuffer()	{}

	DECLARE_NO_COPY_CLASS(TBuffer)

private:
	CPrivateHeap&	heap;

private:
	ULONG_PTR		id;
	int				length;
	DWORD			freeTime;

private:
	TBuffer*		next;
	TBuffer*		last;

	CCriSec			cs;
	TItemList		items;
};

class CBufferPool
{
	using TBufferList	= CRingPool<TBuffer>;
	using TBufferQueue	= CCASQueue<TBuffer>;
	using TBufferCache	= CRingCache<TBuffer, ULONG_PTR, true>;

public:
	void		PutFreeBuffer	(ULONG_PTR dwID);
	TBuffer*	PutCacheBuffer	(ULONG_PTR dwID);
	TBuffer*	FindCacheBuffer	(ULONG_PTR dwID);
	TBuffer*	PickFreeBuffer	(ULONG_PTR dwID);
	void		PutFreeBuffer	(TBuffer* pBuffer);

	void		Prepare			();
	void		Clear			();

private:
	void ReleaseGCBuffer	(BOOL bForce = FALSE);

public:
	void SetItemCapacity	(DWORD dwItemCapacity)		{m_itPool.SetItemCapacity(dwItemCapacity);}
	void SetItemPoolSize	(DWORD dwItemPoolSize)		{m_itPool.SetPoolSize(dwItemPoolSize);}
	void SetItemPoolHold	(DWORD dwItemPoolHold)		{m_itPool.SetPoolHold(dwItemPoolHold);}

	void SetMaxCacheSize	(DWORD dwMaxCacheSize)		{m_dwMaxCacheSize	= dwMaxCacheSize;}
	void SetBufferLockTime	(DWORD dwBufferLockTime)	{m_dwBufferLockTime	= dwBufferLockTime;}
	void SetBufferPoolSize	(DWORD dwBufferPoolSize)	{m_dwBufferPoolSize	= dwBufferPoolSize;}
	void SetBufferPoolHold	(DWORD dwBufferPoolHold)	{m_dwBufferPoolHold	= dwBufferPoolHold;}

	DWORD GetItemCapacity	()							{return m_itPool.GetItemCapacity();}
	DWORD GetItemPoolSize	()							{return m_itPool.GetPoolSize();}
	DWORD GetItemPoolHold	()							{return m_itPool.GetPoolHold();}

	DWORD GetMaxCacheSize	()							{return m_dwMaxCacheSize;}
	DWORD GetBufferLockTime	()							{return m_dwBufferLockTime;}
	DWORD GetBufferPoolSize	()							{return m_dwBufferPoolSize;}
	DWORD GetBufferPoolHold	()							{return m_dwBufferPoolHold;}

	TBuffer* operator []	(ULONG_PTR dwID)			{return FindCacheBuffer(dwID);}

public:
	CBufferPool(DWORD dwPoolSize	 = DEFAULT_BUFFER_POOL_SIZE,
				DWORD dwPoolHold	 = DEFAULT_BUFFER_POOL_HOLD,
				DWORD dwLockTime	 = DEFAULT_BUFFER_LOCK_TIME,
				DWORD dwMaxCacheSize = DEFAULT_MAX_CACHE_SIZE)
	: m_dwBufferPoolSize(dwPoolSize)
	, m_dwBufferPoolHold(dwPoolHold)
	, m_dwBufferLockTime(dwLockTime)
	, m_dwMaxCacheSize(dwMaxCacheSize)
	{

	}

	~CBufferPool()	{Clear();}

	DECLARE_NO_COPY_CLASS(CBufferPool)

public:
	CPrivateHeap&	GetPrivateHeap()	{return m_heap;}
	CItemPool&		GetItemPool()		{return m_itPool;}

public:
	static const DWORD DEFAULT_MAX_CACHE_SIZE;
	static const DWORD DEFAULT_ITEM_CAPACITY;
	static const DWORD DEFAULT_ITEM_POOL_SIZE;
	static const DWORD DEFAULT_ITEM_POOL_HOLD;
	static const DWORD DEFAULT_BUFFER_LOCK_TIME;
	static const DWORD DEFAULT_BUFFER_POOL_SIZE;
	static const DWORD DEFAULT_BUFFER_POOL_HOLD;

private:
	DWORD			m_dwMaxCacheSize;
	DWORD			m_dwBufferLockTime;
	DWORD			m_dwBufferPoolSize;
	DWORD			m_dwBufferPoolHold;

	CPrivateHeap	m_heap;
	CItemPool		m_itPool;

	TBufferCache	m_bfCache;

	TBufferList		m_lsFreeBuffer;
	TBufferQueue	m_lsGCBuffer;
};
